#pragma once

#include <vector>
#include <string>
#include <unordered_map>
#include <memory>

#include "backend.h"

class SymbolTable;
class BaseSymbol;

class BaseSymbol {
    public:
        BaseSymbol();
        
        void setName(std::string name);
        std::string getName();

        void setType(std::string name);
        std::string getType();
        
        llvm::Value* getValue();
        void setValue(llvm::Value* value);
        llvm::AllocaInst* getAddr();
        void setAddr(llvm::AllocaInst* addr);
    private:
        llvm::Value* value;
        llvm::AllocaInst* addr;
        std::string name;
        std::string type;
};

// class FuncSymbol: BaseSymbol {
//     public:
//     private:
//         FuncProperties func_properties;
// };

// class ArraySumbol: BaseSymbol {
//     public:
//     private:
//         ArrayProperties array_properties;
// };

// class StructSymbol: BaseSymbol {
//     public:
//     private:
//         StructProperties struct_properties;
// };

class SymbolTable{
    public:
        bool contains(const std::string name);
        bool insert(std::shared_ptr<BaseSymbol> symbol);
        std::shared_ptr<BaseSymbol> find(const std::string &name);
        std::shared_ptr<SymbolTable> father=nullptr;
        std::shared_ptr<SymbolTable> newScope();
    private:
        std::unordered_map<std::string, std::shared_ptr<BaseSymbol>> table;
};
